import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:demo/core/channel/app_channel.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

/// 用于读取原生资源中的图片
class NativeImageProvider extends ImageProvider<NativeImageProvider> {
  /// 图片名字
  final String imageName;

  /// 缩放
  final double scale;

  /// 数据源
  final Uint8List? bytes;

  /// 文件放在的目录
  final String defType;

  /// 是否加载ios的启动图
  final bool isIosSplashImage;

  const NativeImageProvider(
    this.imageName, {
    this.bytes,
    this.scale = 1.0,
    this.defType = "drawable",
    this.isIosSplashImage = false,
  });

  @override
  ImageStreamCompleter load(NativeImageProvider key, DecoderCallback decode) {
    InformationCollector? collector;
    assert(() {
      collector = () sync* {
        yield DiagnosticsProperty<ImageProvider>('Image provider', this);
        yield DiagnosticsProperty<NativeImageProvider>('Image key', key);
      };
      return true;
    }());
    return MultiFrameImageStreamCompleter(
      codec: _loadAsync(key, decode),
      scale: key.scale,
      debugLabel: key.imageName,
      informationCollector: collector,
    );
  }

  Future<ui.Codec> _loadAsync(NativeImageProvider key, DecoderCallback decode) async {
    if (key.bytes != null && bytes!.lengthInBytes > 0) return decode(key.bytes!);
    Uint8List? data;
    try {
      data = Platform.isIOS && key.isIosSplashImage
          ? await AppChannel.getSplashImageResource
          : await AppChannel.getImageResource(key.imageName, defType: key.defType);
    } catch (e) {
      PaintingBinding.instance!.imageCache!.evict(key);
      rethrow;
    }
    if (data == null || data.lengthInBytes == 0) {
      PaintingBinding.instance!.imageCache!.evict(key);
      throw StateError('Unable to read data');
    }
    return decode(data);
  }

  @override
  Future<NativeImageProvider> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<NativeImageProvider>(this);
  }
}
